﻿using AgCIM.Tools.SpatialEncoding.Beidou.Common;
using NetTopologySuite.Mathematics;

namespace AgCIM.Tools.SpatialEncoding.Beidou
{
    public class CoordinateUtils
    {
        public const double RADIANS_PER_DEGREE = Math.PI / 180.0;

        public static double ToRadians(double degrees)
        {
            if (degrees == null)
            {
                throw new ArgumentException("Degrees is required.");
            }
            return degrees * RADIANS_PER_DEGREE;
        }        
    }

    public class Cartographic
    {
        public double Longitude { get; set; }
        public double Latitude { get; set; }
        public double Height { get; set; }

        public Cartographic(double longitude, double latitude, double height)
        {
            this.Longitude = longitude;
            this.Latitude = latitude;
            this.Height = height;
        }

        public static Cartographic FromDegrees(double longitude, double latitude, double? height = null, Cartographic result = null)
        {
            // 检查输入参数类型
            if (longitude < -180.0 || longitude > 180.0)
            {
                throw new ArgumentOutOfRangeException(nameof(longitude), "Longitude must be between -180 and 180 degrees.");
            }
            if (latitude < -90.0 || latitude > 90.0)
            {
                throw new ArgumentOutOfRangeException(nameof(latitude), "Latitude must be between -90 and 90 degrees.");
            }

            longitude = LatLonHelper.Degree2rad(longitude);
            latitude = LatLonHelper.Degree2rad(latitude);

            return FromRadians(longitude, latitude, height, result);
        }

        public static Cartographic FromRadians(double longitude, double latitude, double? height = null, Cartographic result = null)
        {
            // 检查输入参数类型
            if (result == null)
            {
                return new Cartographic(longitude, latitude, height ?? 0.0);
            }

            result.Longitude = longitude;
            result.Latitude = latitude;
            result.Height = height ?? 0.0;
            return result;
        }

        public static Cartographic FromCartesian3(Vector3D cartesian)
        {
            Vector3D v = GisUtilDouble.CesiumFromCartesian(cartesian);
            var lng = LatLonHelper.Rad2degree(v.X);
            var lat = LatLonHelper.Rad2degree(v.Y);
            var height = v.Z;
            Cartographic cartographic = new Cartographic(lng, lat, height);
            return cartographic;
        }

        public static Cartographic DegreeCartographic(Cartographic cartographic)
        {
            var lng = LatLonHelper.Rad2degree(cartographic.Longitude);
            var lat = LatLonHelper.Rad2degree(cartographic.Latitude);
            var height = cartographic.Height;

            return new Cartographic(lng, lat, height);
        }
    }

}